package com.qdxwx.payment.alipay;

import com.qdxwx.common.utils.TKConvert;
import com.qdxwx.models.order.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ZhiYong
 * @createTime 2020/12/15
 * @description
 */
public class AliPay {

    private static final Logger logger = LoggerFactory.getLogger(AliPay.class);

    public static String gotoAlipay(Order order, Map<String, Object> aliConfig) {
        try {
            String paygateway = "https://mapi.alipay.com/gateway.do?"; // 支付接口（不可以修改）
            String service = "create_direct_pay_by_user";// 快速付款交易服务（不可以修改）
            String sign_type = "MD5";// 文件加密机制（不可以修改）
            String out_trade_no = order.getOrderNo();// guidGeneratorService.gainCode("PAY", true);// 商户网站订单（也就是外部订单号，是通过客户网站传给支付宝，不可以重复） 用时间戳代替了
            String input_charset = "utf-8"; // （不可以修改）
            // partner和key提取方法：登陆签约支付宝账户--->点击“商家服务”就可以看到
            String partner = (String) aliConfig.get("partnerId"); // 支付宝合作伙伴id
            // (账户内提取)
            String key = (String) aliConfig.get("payKey"); // 支付宝安全校验码(账户内提取)
            //String body = LoginUser.getUserId(request) + "-" + orderNo + "-" + out_trade_no;
            String body = order.getDescription();
            // 商品描述，推荐格式：商品名称（订单编号：订单编号）
            String total_fee = order.getCashAmount().toString();// 订单总价,差价尚须银行支付的金额
            // total_fee = String.valueOf(total_fee); // 订单总价
            String payment_type = "1";// 支付宝类型.1代表商品购买（目前填写1即可，不可以修改）
            String seller_email = (String) aliConfig.get("sellerEmail"); // 卖家支付宝帐户
            // subject 商品名称
            String subject = "订单号:" + order.getOrderNo();
            // 扩展信息,存用户id和orderNo.重要，必须存
            String extra_common_param = order.getUserId() + "," + order.getOrderNo();
            String path = "https://www.youtike.com";
            String show_url = path + "/course/index.html"; // 商品地址，
            // 根据集成的网站而定
            // 回调的地址
            //"CommonConstants.contextPath";
            String notify_url = path + "/order/alipay/notify"; // 通知接收URL(本地测试时，服务器返回无法测试)
            String return_url = path + "/order/alipay/return.html"; // 支付完成后跳转返回的网址URL
            // 注意以上两个地址 要用 http://格式的完整路径

            String submiturl = AliPay.CreateUrl(paygateway, service, sign_type, out_trade_no, input_charset, partner, key, show_url, body, total_fee, payment_type, seller_email, subject, notify_url, return_url, extra_common_param);
            logger.info(" submiturl:" + submiturl);
            return "redirect:" + submiturl;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 支付宝返回数据的校验
     */
    public static boolean getAlipayCheckInfo(HttpServletRequest request,Map<String, Object> aliConfig) throws Exception {
        String partner = (String) aliConfig.get("partnerId"); // 支付宝合作伙伴id
        String privateKey =  (String) aliConfig.get("payKey"); // 支付宝安全校key
        String alipayNotifyURL = "http://notify.alipay.com/trade/notify_query.do?" + "partner=" + partner + "&notify_id=" + request.getParameter("notify_id");
        String responseTxt = AliPayUtils.check(alipayNotifyURL);
        //效验失败
        if (!responseTxt.equals("true")) {
            logger.info("支付宝返回数据效验失败  ---responseTxt---" + responseTxt);
            return false;
        }
        Map<String, Object> params = new HashMap<>();
        // 获得POST 过来参数设置到新的params中
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //中文商品名称 转码
            if ("subject".equals(name.trim())) {
                valueStr = URLDecoder.decode(valueStr, "gb2312");
            } else {
                // 乱码解决，这段代码在出现乱码时使用,但是不一定能解决所有的问题，所以建议写过滤器实现编码控制。
                // 如果mysign和sign不相等也可以使用这段代码转化
                valueStr = new String(valueStr.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); // 乱码解决
            }
            params.put(name, valueStr);
        }
        // 验证加密签名
        String mySign = AliPayUtils.sign(params, privateKey);
        if (!mySign.equals(request.getParameter("sign"))) {
            logger.info("验证加密签名  ---mySign---" + request.getParameter("sign"));
            logger.info("验证加密签名  ---params---" + params);
            return false;
        }
        return true;
    }

    public static String CreateUrl(String payGateway, String service,
                                   String sign_type, String out_trade_no, String input_charset,
                                   String partner, String key, String show_url, String body,
                                   String total_fee, String payment_type, String seller_email,
                                   String subject, String notify_url, String return_url,
                                   String extra_common_param) {

        Map<String, String> params = new HashMap<>();
        params.put("service", service);
        params.put("partner", partner);
        params.put("subject", subject);
        params.put("body", body);
        params.put("out_trade_no", out_trade_no);
        params.put("total_fee", total_fee);
        params.put("show_url", show_url);
        params.put("payment_type", payment_type);
        params.put("seller_email", seller_email);
        params.put("return_url", return_url);
        params.put("notify_url", notify_url);
        params.put("extra_common_param", extra_common_param);
        params.put("_input_charset", input_charset);

        String sign = TKConvert.toMD5(AliPayUtils.getContent(params, key));
        StringBuilder url = new StringBuilder(payGateway);
        List<String> keys = new ArrayList<>(params.keySet());

        try {
            for (String s : keys) {
                url.append(s).append("=").append(URLEncoder.encode(params.get(s), input_charset)).append("&");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return url.append("sign=").append(sign).append("&sign_type=").append(sign_type).toString();

    }
}
